<?php
/**
 * Created by jinqiang on 2024/7/1 17:42.
 * Copyright (c) 2024, Your Company. All rights reserved.
 */


namespace App\Http\Services\Produce;


use App\Http\Models\Mysql\SsyFeishuApprovalBindingTable;
use App\Http\Models\Mysql\SsyJstPurchaseinOrderTable;
use App\Http\Models\Mysql\SsyPricingExamineTable;
use App\Http\Models\Mysql\SsyProcessingListBatchTable;
use App\Http\Models\Mysql\SsyProcessingListShenqingTable;
use App\Http\Models\Mysql\SsyProcessingListTable;
use App\Http\Models\Mysql\SsyProductlistBangdinNewTable;
use App\Http\Models\Mysql\SsyProductlistBangdinTagTable;
use App\Http\Models\Mysql\SsyPurchaseReturnTable;
use App\Http\Models\Mysql\SsyStyleImagesTable;
use App\Http\Repository\FeishuRepository;
use App\Http\Repository\LogRepository;
use App\Http\Repository\OmsRepository;
use App\Http\Repository\RfidRepository;
use App\Http\Repository\WmsRepository;
use Illuminate\Support\Facades\DB;

class ProcessingService
{
    public function search($param)
    {
        $conn = new SsyProcessingListTable();
        if($param['processing_code'] ?? ""){
            $processingCodes = explode(",", $param['processing_code']);
            if(count($processingCodes) > 1){
                $conn = $conn->whereIn('processing_code', $processingCodes);
            } else if(preg_match("/^[a-zA-Z]/is", $param['processing_code'])){
                $conn = $conn->where('processing_code', 'like', $param['processing_code']."%");
            }else{
                $conn = $conn->where('processing_code', 'like', "%".$param['processing_code']."%");
            }
        }
        if($param['sku_code'] ?? ""){
            if(preg_match("/^[a-zA-Z]/is", $param['sku_code'])) {
                $conn = $conn->where('sku_code', 'like', $param['sku_code'] . "%");
            }else{
                $conn = $conn->where('sku_code', 'like', "%".$param['sku_code'] . "%");
            }
        }
        if($param['supplier_id'] ?? ""){
            $conn = $conn->where('supplier_id', $param['supplier_id']);
        }
        if($param['factory_name'] ?? ""){
            $conn = $conn->where('factory_name', 'like', "%".$param['factory_name']."%");
        }
        if($param['type_name'] ?? ""){
            $conn = $conn->where('type_name', 'like', "%".$param['type_name']."%");
        }
        //审核状态
        if(isset($param['s_status']) && $param['s_status'] != ""){
            $conn = $conn->where('s_status', $param['s_status']);
        }
        //推送状态
        if(isset($param['is_oms']) && $param['is_oms'] != ""){
            $conn = $conn->where('is_oms', $param['is_oms']);
        }
        //RFID生成状态
        if(isset($param['is_create']) && $param['is_create']!=""){
            $conn = $conn->where('is_create', $param['is_create']);
        }
        //完结状态
        if(isset($param['f_status']) && $param['f_status']!=""){
            $conn = $conn->where('f_status', $param['f_status']);
        }
        if(isset($param['add_date']) && !empty($param['add_date'])){
            $conn = $conn->whereBetween('add_date', $param['add_date']);
        }
        if($param['order_processor'] ?? ""){
            $conn = $conn->where('order_processor', $param['order_processor']);
        }
        if(isset($param['contract_date_days']) && $param['contract_date_days'] != ""){
            $contractDate = date('Y-m-d', strtotime($param['contract_date_days']." days"));
            $conn = $conn->where('contract_date', $contractDate);
        }
        //用户主体区分
        $user = auth()->guard("api")->user();
        $bandCodes = array_column(config("scm.subject"), 'brand_code_s', 'is_subject');
        if($param['brand_code'] ?? "" || $user['source_from'] == 'fs'){
            $conn = $conn->where('brand_code', $param['brand_code'] ?? $bandCodes[$user->is_subject]);
        }
        $res = $conn->orderBy('createtime', 'desc')->orderBy('id', 'asc')->paginate((Int)$param['limit'], "*", "page", (Int)$param['page'])->toArray();
        //款式图片
        $typeNoList = array_column($res['data'], 'type_no');
        $imgList = (new SsyStyleImagesTable())->whereIn('type_no', $typeNoList)->get(['type_no', 'thumb_images'])->toArray();
        $imgMap = array_column($imgList, 'thumb_images', 'type_no');
        foreach ($res['data'] as &$item){
            //到期预警
            $days = (Int)((strtotime($item['contract_date']) - strtotime(date('Y-m-d'))) / (24*3600));
            $item['contract_date_days'] = $item['f_status'] == 0 && !empty($item['contract_date']) ? $days."天到货" : "";
            //款式图片
            $item['img'] = $imgMap[$item['type_no']] ?? "";
            //入库数
            $qtyJY =  (new SsyJstPurchaseinOrderTable())->where('processing_code', $item['processing_code'])->where('po_id', 'like', "PNO%")
                ->where('sku_id', $item['sku_code'])->where('wh_id', 3)->sum('qty');
            $item['qty'] = $qtyJY;
            //获取增裁数
            $item['zc_num'] = (new SsyProcessingListShenqingTable())->where('processing_code', $item['processing_code'])->where('sku_code', $item['sku_code'])
                ->where('status', 1)->sum('num');
            //溢装比数
            $item['yc_num'] = !empty($item['ly_processing_code']) ? $item['bunum'] : ceil($item['num'] * config('scm.overflow'));
            //未入库数
            $item['not_in_num'] = $item['num'] - $item['bao_number'] - $item['qty'];
        }
        unset($item);
        return [
            'data' => $res['data'],
            'total' => $res['total']
        ];
    }

    public function searchSku($processingCode)
    {
        $field = ["processing_code", "type_no", "type_name", "sku_code"];
        return (new SsyProcessingListTable())->where('processing_code', $processingCode)->groupBy($field)->get($field)->toArray();
    }

    public function rfidCreate($param)
    {
        //1水洗唛  2吊牌  22不生成
        $status = (Int)$param['status'];
        $data = json_decode($param['data'], true);
        $ids = array_column($data, 'id');
        $exist = (new SsyProcessingListTable())->whereIn('id', $ids)->whereIn('is_create', [1, 2])->exists();//1已生成 2不生成
        if(!empty($exist)){
            return ['code' => -1, 'msg' => '创建失败：选项中存在无需生成或已生成状态的成品加工单'];
        }
        //不生成rfid码
        if($status == 22){
            return (new SsyProcessingListTable())->updateData($ids, ['is_create' => 2]);
        }
        $skuCodes = array_unique(array_column($data, 'sku_code'));
        //判断面料信息录入正确
        if($status == 1){
            $infos = (new SsyProductlistBangdinNewTable())->whereIn('sku_code', $skuCodes)->get(['lining_one'])->toArray();
            $infosNotEmpty = array_filter(array_column($infos, 'lining_one'), 'strlen');//排除lining_one为空的对象;
            if(empty($infos) || count($skuCodes) != count($infos) || count($skuCodes) != count($infosNotEmpty)){
                return ['code' => -1, 'msg' => '创建失败：面料未填写, 请补充后再操作！'];
            }
        }elseif ($status == 2){
            //判断吊牌信息录入正确
            $infos = (new SsyProductlistBangdinTagTable())->whereIn('sku_code', $skuCodes)->get(['executive_standard'])->toArray();
            $infosNotEmpty = array_filter(array_column($infos, 'executive_standard'), 'strlen');//排除executive_standard为空的对象;
            if(empty($infos) || count($skuCodes) != count($infos) || count($skuCodes) != count($infosNotEmpty)){
                return ['code' => -1, 'msg' => '创建失败：执行标准参数不全, 请补充后再操作！'];
            }
        }
        //开启数据库事务
        DB::beginTransaction();
        foreach ($data as $item) {
            //创建rfid唯一码
            $createRfidRes = RfidRepository::createNumber($item['processing_code'], $item['type_no'], $item['sku_code'], $item['type_name'],
                $item['color_code'], $item['size_code'], $item['num'], $item['factory_name'], $item['supplier_id']);
            if($createRfidRes['code'] !== 0){
                DB::rollBack();
                return $createRfidRes;
            }
        }
        $res = (new SsyProcessingListTable())->updateData($ids, ['is_create' => 1, 'groups' => $status]);
        if($res['code'] !== 0){
            DB::rollBack();
        }
        DB::commit();
        return $res;
    }

    public function open($param)
    {
        $processingList = (new SsyProcessingListTable())->where('processing_code', $param['processing_code'])->get(['id', 'is_oms'])->toArray();
        $ids = array_column($processingList, 'id');
        $status = (Int)$param['status'];
        return (new SsyProcessingListTable())->updateData($ids, ['status' => $status, 'f_status' => $status==1 ? 0 : 2]);
    }

    public function push($processingCode)
    {
        list($res, $pushData) = OmsRepository::push($processingCode);
        if($res['code'] !== 0){
            return ['code' => -1, 'msg' => '推送失败：'.$res['msg'], 'data' => $res];
        }
        $save = [
            'is_oms' => 1,
            'jy_number' => $res['data']['entryOrderId']
        ];
        //写入日志
        LogRepository::setJuyiPushLog($pushData,2,'创建采购单入库', auth()->guard("api")->user()->name);
        return (new SsyProcessingListTable())->updateDataWhere(['processing_code' => $processingCode], $save);
    }

    public function cancel($processingCode)
    {
        list($res, $cancelData) = OmsRepository::cancel($processingCode);
        if($res['code'] !== 0){
            return ['code' => -1, 'msg' => '取消失败：'.$res['msg'], 'data' => $res];
        }
        //写入日志
        LogRepository::setJuyiPushLog($cancelData,2,'取消采购单', auth()->guard("api")->user()->name);
        //修改推送状态
        return (new SsyProcessingListTable())->updateDataWhere(['processing_code' => $processingCode], ['is_oms' => 0, 'jy_purchase_number' => null]);
    }

    public function end($processingCode)
    {
        $processingObj = (new SsyProcessingListTable())->where('processing_code', $processingCode)->first();
        if(empty($processingObj->jy_purchase_number)){
            return ['code' => -1, 'msg' => '操作失败：未找到采购通知单号！'];
        }
        $subjects = array_column(config("scm.subject"), 'owner_code', 'brand_code_s');
        $wmsRes = WmsRepository::cancel($processingObj->jy_purchase_number, "CGRK", $subjects[$processingObj->brand_code]);
        if($wmsRes['success']){
            $omsRes = OmsRepository::end($processingCode);
            (new SsyProcessingListTable())->updateDataWhere(['processing_code'=>$processingCode], [
                'f_status_time' => date("Y-m-d H:i:s"),
                'f_status_user' => auth()->guard("api")->user()->name,
                "content_remarks" => "后台手动完结",
                'f_status' => 1
            ]);
            return ['code' => 0, 'msg' => $omsRes['code'] !==0 ? $omsRes['msg'] : "完结成功"];
        }else{
            return ['code' => -1, 'msg' => "巨沃完结失败".$wmsRes['body'], 'data' => $wmsRes];
        }
    }

    public function batchSet($processingCode, $batchId)
    {
        $batchObj = (new SsyProcessingListBatchTable())->where('id', $batchId)->first();
        $data = [
            'batch_no' => $batchObj->batch_no,
            'batch_title' => $batchObj->batch_title,
            'batch_date' => $batchObj->batch_date
        ];
        return (new SsyProcessingListTable())->updateDataWhere(['processing_code' => $processingCode], $data);
    }

    //采退、返修
    public function goodReturn($data, $type, $remark)
    {
        $data = json_decode($data, true);
        $number="CGTH".auth()->guard("api")->user()->id.date('YmdHis');
        $groups = $type == "FX" ? 1 : 0;
        if(empty($data)){
            return ['code' => -1, 'msg' => '没有需要处理的数据'];
        }
        $skuCodes = array_column($data, 'sku_code');
        $processingList = (new SsyProcessingListTable())->where('processing_code', $data[0]['processing_code'])->whereIn('sku_code', $skuCodes)->get()->toArray();
        $processingMap = array_column($processingList, null, 'sku_code');
        //判断核价审核是否提交审核  避免返修回来的实付价格为0
        $pricingObj = (new SsyPricingExamineTable())->where('processing_code', $data[0]['processing_code'])->where('status', 2)->exists();
        if(empty($pricingObj) &&  $processingList[0]['brand_code'] != 'Q'){
            return ['code' => -1, 'msg' => '创建失败：前往提交核价审核, 避免采退返修实付价为0'];
        }
        //开启数据库事务
        DB::beginTransaction();
        foreach($data as $item){
            if((Int)$item['num'] <= 0){
                DB::rollBack();
                return ['code' => -1, 'msg' => '创建失败：计划数量必须【大于0】'];
            }
            $poId = ($processingMap[$item['sku_code']]['po_id'] ?: "") . ( !empty($processingMap[$item['sku_code']]['jy_number']) ?
                    $processingMap[$item['sku_code']]['jy_number'] : "");
            $saveData = [
                "processing_code" => $item['processing_code'],
                "number" => $number,
                "sku_code" => $item['sku_code'],
                "po_id" => $poId,
                "type_name" => $item['type_name'],
                "type_no"=> $item['type_no'],
                "color_code" => $processingMap[$item['sku_code']]['color_code'],
                "size_code" => $processingMap[$item['sku_code']]['size_code'],
                "num" => (Int)$item['num'],
                "factory_name" => $processingMap[$item['sku_code']]['factory_name'],
                "adduser" => auth()->guard("api")->user()->name,
                "groups" => $groups,
                "remark" => $remark,
                "createtime" => date("Y-m-d H:i:s")
            ];
            $res = (new SsyPurchaseReturnTable())->createData($saveData);
            if($res['code'] !== 0){
                DB::rollBack();
                return $res;
            }
        }
        $remark = $type == "FX" ? "【返修-备注】" : "";
        list($res, $pushData) = OmsRepository::stickout($data, $processingMap, $remark);
        if($res['code'] !== 0){
            DB::rollBack();
            return ['code' => -1, 'msg' => $res['msg']];
        }
        DB::commit();
        //写入日志
        LogRepository::setJuyiPushLog($pushData,3,'出库单', auth()->guard("api")->user()->name);
        return (new SsyPurchaseReturnTable())->updateDataWhere(['number' => $number], ['jy_number' => $res['data']['deliveryOrderId'], 'is_push' => 1]);
    }

    public function baociSet($data)
    {
        $data = json_decode($data, true);
        //开启数据库事务
        DB::beginTransaction();
        foreach($data as $item) {
            $num = (Int)($item['num'] ?? 0);
            if ($num < 0) {
                DB::rollBack();
                return ['code' => -1, 'msg' => '创建失败：计划数量必须【大于0】'];
            }
            $where = [
                'sku_code' => $item['sku_code'],
                'processing_code' => $item['processing_code']
            ];
            $res =(new SsyProcessingListTable())->updateDataWhere($where, ['bao_number' => $num]);
            if($res['code'] !== 0){
                DB::rollBack();
                return $res;
            }
        }
        DB::commit();
        return ['code' => 0, 'msg' => '报次成功'];
    }

    //创建增裁审批
    public function zengcSet($data)
    {
        $data = json_decode($data, true);
        $processingShenqingObj = (new SsyProcessingListShenqingTable())->where('processing_code', $data[0]['processing_code'])->orderBy('id', 'desc')->first();
        $number = !empty($processingShenqingObj) ? (Int)($processingShenqingObj->number)+1 : 1;
        $processingCodeNew = 'ZC'.trim($data[0]['processing_code'])."0".$number;
        if($number >= 10){
            $processingCodeNew = 'ZC'.trim($data[0]['processing_code']).$number;
        }
        $skuCodes = array_column($data, 'sku_code');
        $processingList = (new SsyProcessingListTable())->where('processing_code', $data[0]['processing_code'])->whereIn('sku_code', $skuCodes)->get()->toArray();
        $processingMap = array_column($processingList, null, 'sku_code');
        //开启数据库事务
        DB::beginTransaction();
        $totalNum = 0;
        $detailStr = "";
        foreach ($data as $item){
            if ((int)$item['num'] <= 0) {
                DB::rollBack();
                return ['code' => -1, 'msg' => '创建失败：补码数量必须【大于0】'];
            }
            if($processingMap[$item['sku_code']]['source_type'] >= 5){
                DB::rollBack();
                return ['code' => -1, 'msg' => '创建失败：出现不符合增裁的加工单类型'];
            }
            $saveData = [
                'type_name' => $item['type_name'],
                'type_no' => $item['type_no'],
                'color_code' => $processingMap[$item['sku_code']]['color_code'],
                'size_code' => $processingMap[$item['sku_code']]['size_code'],
                'num' => (Int)$item['num'],
                'sku_code' => $item['sku_code'],
                'processing_code' => $item['processing_code'],
                'factory_name' => $processingMap[$item['sku_code']]['factory_name'],
                'new_processing_code' => $processingCodeNew,
                'number' => $number,
                'adduser' => auth()->guard("api")->user()->name,
                'createtime'=>date('Y-m-d H:i:s')
            ];
            $totalNum += (Int)$item['num'];
            $detailStr .= '[{"id": "sku_code","type":"input","value":"'.trim($item['sku_code']).'"},{"id": "num","type":"input","value":"'.trim($item['num']).'"}],';
            $res = (new SsyProcessingListShenqingTable())->createData($saveData);
            if($res['code'] !== 0){
                DB::rollBack();
                return $res;
            }
        }
        $subjects = array_column(config("scm.subject"), null, 'is_subject');
        $user = auth()->guard("api")->user()->toArray();
        $detailStr = trim(rtrim($detailStr, ","), '"');
        $approvalSubject = in_array($user['is_subject'], ['kz', 'mz', 'qyx']) ? 'kz' : $user['is_subject'];
        $fsUserId = $user[$approvalSubject.'_feishu_user_id'];
        $fsOpenId = $user[$approvalSubject.'_feishu_open_id'];
        $fsApprovalCode = $subjects[$approvalSubject]['zc_approval_code'];
        $subjectLabelMap = ["kz" => "mcix5ku0-pdat4ympa6-0", "mz" => "mcix5ku0-vdpcqfaupsl-0", "qyx" => "mcix5ku0-ghj6t31j40c-0"];
        //$fsApprovalCode = "486A13CC-C0D5-4790-BF9B-00302B2580DD";//测试
        //$subjectLabelMap = ["kz" => "mciuy2zg-kgzrae9i4tc-0", "mz" => "mciuy2zg-vptbk224ias-0", "qyx" => "mciuy2zg-6l942nhxb8b-0"];//测试
        //品牌字段
        $brandStr = $approvalSubject == "kz" ? '{"id":"is_subject","type":"radioV2","value":"'.$subjectLabelMap[$user['is_subject']].'"},' : "";
        $postData = [
            "approval_code" => $fsApprovalCode,
            "user_id" => $fsUserId,
            "open_id" => $fsOpenId,
            "form"=>'['.$brandStr.'{"id":"processing_code","type":"input","value":"'
                .trim($processingList[0]['processing_code']).'"},{"id":"type_name","type":"input","value":"'
                .trim($processingList[0]['type_name']).'"},{"id":"factory_name","type":"input","value":"'.trim($processingList[0]['factory_name'])
                .'"},{"id": "detaillist","type": "fieldList","value": ['.$detailStr.']},{"id":"totalnum","type":"input","value":"'.$totalNum.'"}]'
        ];
        $res = (new FeishuRepository($approvalSubject))->createApproval($postData);
        if($res['code'] != '0'){
            DB::rollBack();
            return ['code' => -1, 'msg' => '创建增裁,失败!'.($res['msg']??""), 'data' => $res];
        }
        $createRes = (new SsyFeishuApprovalBindingTable())->createData([
            "instance_code" => $res['data']['instance_code'],
            "data_id" => $processingCodeNew,
            "types" => 5,
            "createtime" => date('Y-m-d H:i:s')
        ]);
        if($createRes['code'] !== 0){
            DB::rollBack();
            return $createRes;
        }
        DB::commit();
        return $createRes;
    }

    //创建增裁加工单
    public function zengcCreate($processingCode)
    {
        $processingNewList = (new SsyProcessingListShenqingTable())->where('new_processing_code', $processingCode)
            ->get(["processing_code","new_processing_code","sku_code","num"])->toArray();
        $processingList = (new SsyProcessingListTable())->where('processing_code', $processingNewList[0]['processing_code'])
            ->whereIn('sku_code', array_column($processingNewList, 'sku_code'))->get()->toArray();
        $processingMap = array_column($processingList, null, 'sku_code');
        DB::beginTransaction();
        foreach ($processingNewList as $item) {
            $processingObj = $processingMap[$item['sku_code']];
            $unitPrice = (Double)($processingObj['unit_price'] ?: 0);
            $batchDate = $processingObj['batch_date'] ?: "2020-01-10";
            $addDate = $processingObj['add_date'] ?: "2020-01-10";
            $data = [
                'type_name' => $processingObj['type_name'],
                'type_no' => $processingObj['type_no'],
                'color_code' => $processingObj['color_code'],
                'size_code' => $processingObj['size_code'],
                'num' => $item['num'],
                'sku_code' => $processingObj['sku_code'],
                'processing_code' => $item['new_processing_code'],
                'factory_name' => $processingObj['factory_name'],
                'equipment_number' => $processingObj['equipment_number'],
                'ly_processing_code' => $processingObj['processing_code'],
                'factory_contract_no' => $processingObj['factory_contract_no'],
                'countprice' => $item['num'] * $unitPrice,
                'embroidery_price' => $processingObj['embroidery_price'],
                'contract_date' => $processingObj['contract_date'],
                'production_date' => $processingObj['production_date'],
                'merchandiser' => $processingObj['merchandiser'],
                'order_processor' => $processingObj['order_processor'],
                'adduser' => $processingObj['adduser'],
                'embroidery_factory' => $processingObj['embroidery_factory'],
                'printing_factory' => $processingObj['printing_factory'],
                'bronzing_factory' => $processingObj['bronzing_factory'],
                'gold_printing_factory' => $processingObj['gold_printing_factory'],
                'source_type' => 5,
                'add_date' => $addDate,
                'total_price' => $item['num'] * $unitPrice,
                'unit_price' => $unitPrice,
                'supplier_id' => $processingObj['supplier_id'],
                'verify_price_number' => $processingObj['verify_price_number'],
                's_status' => $processingObj['s_status'],
                'verify_price_style_number' => $processingObj['verify_price_style_number'],
                'export_order_number' => $processingObj['export_order_number'],
                'embroidery_supplier_id' => $processingObj['embroidery_supplier_id'],
                'settlement_method' => $processingObj['settlement_method'],
                'bao_number'=> 0,
                'batch_no' => $processingObj['batch_no'],
                'batch_title' => $processingObj['batch_title'],
                'batch_date' => $batchDate,
                'is_create'=> 0,//是否生成rifid码 0未设置 1已生成  2不生成
                'groups' => $processingObj['groups'],
                'brand_name' => $processingObj['brand_name'],
                'brand_code' => $processingObj['brand_code'],
                'createtime' => date('Y-m-d H:i:s')
            ];
            $res = (new SsyProcessingListTable())->createData($data);
            if($res['code'] !== 0){
                DB::rollBack();
                return $res;
            }
        }
        DB::commit();
        return ['code' => 0];
    }
}
